package com.github.xzb617.client.config.task;

import com.github.xzb617.client.config.refresher.ConfigurableContextRefresher;
import com.github.xzb617.client.config.serv.Config;
import com.github.xzb617.client.config.serv.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

/**
 * 定期拉取配置看有没有配置更新
 * <p>1.对长轮询小概率出现的漏掉更新通知进行兜底</p>
 * <p>2.每5分钟执行一次</p>
 * @author xzb617
 */
public class FixedTimeGetConfigRunnable implements Runnable {

    /**
     * 日志
     */
    private final static Logger LOGGER = LoggerFactory.getLogger(FixedTimeGetConfigRunnable.class);

    private Config lastConfig;
    private final ConfigService configService;
    private final ConfigurableContextRefresher configurableContextRefresher;

    public FixedTimeGetConfigRunnable(ConfigService configService, ConfigurableContextRefresher configurableContextRefresher) {
        this.configService = configService;
        this.configurableContextRefresher = configurableContextRefresher;
    }

    @Override
    public void run() {
        try {
            Config config = this.configService.getConfigStatus();
            boolean modified = isConfigChanged(config);
            if (modified) {
                // 有配置文件更新
                this.lastConfig = config;
                this.configurableContextRefresher.refreshEnvironment();
            } else {
                LOGGER.info("No remote configuration can be refreshed.");
            }
        } catch (Throwable e) {
            LOGGER.error("An error occurred while executing the scheduled pull configuration, cause by {}", e.getMessage(), e);
        }
    }


    /**
     * 判断配置文件相较于上次是否发生了变化
     * @return
     */
    private boolean isConfigChanged(Config config) {
        // 没有上一次的记录，则表示有配置更新
        if (this.lastConfig == null) {
            return true;
        }
        // 比较 配置
        boolean configChanged = compare(this.lastConfig.getConfigReleaseTime(), config.getConfigReleaseTime(), this.lastConfig.getConfigSign(), config.getConfigSign());
        if (configChanged) {
            return true;
        }
        // 比较 限流
        boolean flowChanged = compare(this.lastConfig.getFlowChangedTime(), config.getFlowChangedTime(), this.lastConfig.getFlowSign(), config.getFlowSign());
        if (flowChanged) {
            return true;
        }
        // 比较 路由
        boolean routeChanged = compare(this.lastConfig.getRouteChangedTime(), config.getRouteChangedTime(), this.lastConfig.getRouteSign(), config.getRouteSign());
        if (routeChanged) {
            return true;
        }
        return false;
    }


    private boolean compare(Long time1, Long time2, String sign1, String sign2) {
        return time2 > time1 && !sign2.equals(sign1);
    }

}
